package com.xhy.documents_collection.service.task.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhy.documents_collection.holder.UserHolder;
import com.xhy.documents_collection.entity.PO.task.*;
import com.xhy.documents_collection.mapper.task.GroupMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhy.documents_collection.service.task.*;
import com.xhy.documents_collection.utils.OSSUtil;
import com.xhy.documents_collection.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xhy
 * @since 2022-11-22
 */
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {


    @Resource
    private TaskService taskService;

    @Resource
    private TaskRecordService taskRecordService;

    @Resource
    private TroopService troopService;

    @Resource
    private TroopUserService troopUserService;


    /**
     * 对方有队伍以及自己有队伍则不能邀请
     * 两人互相邀请过才可组队
     * 双方没队伍则随机选择一个人的任务记录删除
     * 双方有一方有队伍则选择没有队伍的人的任务记录删除
     * @param taskId 任务id
     * @param inviteId 邀请者id
     * @return
     */
    @Override
    @Transactional
    public R invite(Integer taskId, Integer inviteId) {

        if (ObjectUtils.isEmpty(taskId) || ObjectUtils.isEmpty(inviteId)){
            return R.error().message("参数为空");
        }

        // 是否可以组队
        Task task = taskService.get(taskId);
        if (task.getIsGroup() == 0){
            return R.error().message("不允许组队");
        }
        Integer uId = UserHolder.get();
        // 不能邀请同一个人
        if (uId.compareTo(inviteId) == 0){
            return R.error().message("邀请人和被邀请人不能是同一个");
        }

        // 如果自己提交过文件则不能组队
        TaskRecord taskRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", uId).select("is_submit","id"));

        if (taskRecord.getIsSubmit()){
            return R.error().message("请撤回文件后再组队,轻装上阵哦~");
        }

        // 1. 是否邀请过
        Group group = getOne(new QueryWrapper<Group>().eq("task_id", taskId).eq("u_id", uId).eq("invite_id", inviteId));
        if (!ObjectUtils.isEmpty(group)){
            return R.error().message("不可重复邀请");
        }

        // 人数限制
        Integer groupUserLimit = task.getGroupUserLimit();
        // 0.对方有队伍的情况下
        TaskRecord otherRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", inviteId).select("troop_id","id"));
        if (otherRecord.getTroopId()!=-1){
            // 1.对方是否达到人数限制
            int count = troopUserService.count(new QueryWrapper<TroopUser>().eq("troop_id", otherRecord.getTroopId()));
            if (count>=groupUserLimit){
                return R.error().message("对方队伍人数已满");
            }
        }
        // 2.已方是否达到人数限制
        TaskRecord selfRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", uId).select("troop_id","id"));
        if (selfRecord.getTroopId()!=-1){
            int count = troopUserService.count(new QueryWrapper<TroopUser>().eq("troop_id", selfRecord.getTroopId()));
            if (count>=groupUserLimit){
                return R.error().message("已方队伍人数已满");
            }
        }
        // 3.邀请的人是否已达到人数限制,当前队伍人数限制3人,邀请人数不能超过3人
        int count1 = count(new QueryWrapper<Group>().eq("task_id", taskId).eq("u_id", uId));
        if (count1>=groupUserLimit){
            return R.error().message("邀请人数已达限制");
        }

        // 2. 当前邀请是否已经达到互相邀请
        group = getOne(new QueryWrapper<Group>().eq("task_id", taskId).eq("u_id", inviteId).eq("invite_id", uId));
        String message = "邀请成功";
        try{
            if (!ObjectUtils.isEmpty(group)){
                // 3 组队
                // 3.1 如果双方拥有队伍则不能邀请
                Integer isSelfGroup = selfRecord.getTroopId();

                Integer isOtherGroup = otherRecord.getTroopId();
                if (isSelfGroup !=-1 && isOtherGroup !=-1){
                    return R.error().message("你们俩已经有队伍了");
                }else if (isSelfGroup == -1 && isOtherGroup == -1){
                    // 3.2 双方没有队伍
                    // 1.创建队伍
                    Troop troop = new Troop();
                    troop.setName("t");
                    troopService.save(troop);
                    Integer troopId = troop.getId();

                    // 2.创建关联表
                    TroopUser troopUser = new TroopUser();
                    troopUser.setTroopId(troopId);
                    troopUser.setUId(uId);
                    TroopUser troopUser1 = new TroopUser();
                    troopUser1.setTroopId(troopId);
                    troopUser1.setUId(inviteId);
                    troopUserService.save(troopUser);
                    troopUserService.save(troopUser1);
                    // 修改对方记录->到同一个组队
                    TaskRecord record = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", inviteId));
                    record.setTroopId(troopId);
                    taskRecordService.updateById(record);
                    // 补充表关联
                    taskRecord.setTroopId(troopId);
                    taskRecordService.updateById(taskRecord);
                    remove(new QueryWrapper<Group>().eq("task_id",taskId).eq("u_id",inviteId).eq("invite_id",uId));

                }else {
                    // 3.3双方有一方有队伍
                    Integer troopId = isSelfGroup !=-1 ? isSelfGroup : isOtherGroup;
                    // 修改没有队伍的用户的记录
                    Integer waitSetUid = isSelfGroup != -1 ? inviteId : uId;
                    // 曲线救国形式
                    int count = troopUserService.count(new QueryWrapper<TroopUser>().eq("troop_id", troopId).eq("u_id", group.getInviteId()));
                    TroopUser troopUser = new TroopUser();
                    troopUser.setTroopId(troopId);
                    troopUser.setUId(count == 0 ? group.getInviteId() : group.getUId());
                    troopUserService.save(troopUser);
                    TaskRecord record = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", waitSetUid));
                    record.setTroopId(troopId);
                    taskRecordService.updateById(record);
                    // 删除队伍中邀请过该用户的记录
                    // 查出队伍中的成员
                    List<Integer> userIds = troopUserService.list(new QueryWrapper<TroopUser>().eq("troop_id", troopId).select("u_id")).stream().map(TroopUser::getUId).collect(Collectors.toList());
                    for (Integer userId : userIds) {
                        remove(new QueryWrapper<Group>().eq("task_id",taskId).eq("u_id",userId).eq("invite_id",group.getInviteId()));
                    }
                }
                // 2.2删除group中邀请记录
            }else {
                // 如果有一方有队伍的情况下邀请对方
                // 查看自己队伍情况
                TaskRecord record = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", uId).select("id", "troop_id"));
                if (record.getTroopId()!=-1){
                    // 有队伍
                    // 查出队伍中的人员->所有人都邀请这个人
                    List<Integer> userIds = troopUserService.list(new QueryWrapper<TroopUser>().eq("troop_id", record.getTroopId()).select("u_id")).stream().map(TroopUser::getUId).collect(Collectors.toList());
                    List<Group> groups = new ArrayList<>();
                    for (Integer userId : userIds) {
                        Group g = new Group();
                        g.setTaskId(taskId);
                        g.setUId(userId);
                        g.setInviteId(inviteId);
                        groups.add(g);
                    }
                    saveBatch(groups);
                }else {
                    // 没队伍
                    group = new Group();
                    // 邀请对方
                    group.setUId(uId);
                    group.setInviteId(inviteId);
                    group.setTaskId(taskId);
                    save(group);
                }
                message = "组队成功";
            }
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error().message("邀请失败,请联系管理员");
        }

        return R.ok().message(message);
    }



    @Override
    public R cancelInvite(Integer taskId, Integer inviteId) {

        Integer uId = UserHolder.get();
        if (uId.compareTo(inviteId) == 0){
            return R.error().message("取消邀请人和邀请人不能是同一个");
        }
        Group group = getOne(new QueryWrapper<Group>().eq("task_id", taskId).eq("u_id", uId).eq("invite_id", inviteId));
        if (group == null){
            return R.error().message("没有要取消邀请的人");
        }
        // 如果是有队伍的情况下取消邀请,则把所有成员的邀请记录都删除
        // 查找自己队伍情况
        TaskRecord taskRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().eq("t_id", taskId).eq("u_id", uId));
        if (taskRecord.getTroopId()!=-1){
            // 查出队伍成员信息
            List<Integer> userIds = troopUserService.list(new QueryWrapper<TroopUser>().eq("troop_id", taskRecord.getTroopId()).select("u_id")).stream().map(TroopUser::getUId).collect(Collectors.toList());
            // 删除
            for (Integer userId : userIds) {
                remove(new QueryWrapper<Group>().eq("task_id",taskId).eq("u_id",userId));
            }
        }else {
            removeById(group);

        }
        return R.ok().message("取消邀请成功");
    }

    @Override
    @Transactional
    public R exitGroup(Integer taskRecordId) {
        Integer uId = UserHolder.get();

        // 设置自己记录表中troop_id为-1
        TaskRecord taskRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().select("id","troop_id","t_id").eq("id", taskRecordId));
        Integer taskId = taskRecord.getTId();
        Integer troopId = taskRecord.getTroopId();
        if (troopId == -1){
            return R.error().message("没有队伍咋退出");
        }
        // 在组队表中查询是否有该用户自己
        TroopUser troopUser = troopUserService.getOne(new QueryWrapper<TroopUser>().eq("troop_id", troopId).eq("u_id", uId));
        if (troopUser == null){
            return R.error().message("队伍中没有你");
        }
        taskRecord.setTroopId(-1);
        // 如果当前队伍中只剩下两人,则把队伍删除
        int count = troopUserService.count(new QueryWrapper<TroopUser>().eq("troop_id", troopId));

        // 删除troop_user表中关联关系
        try{
            if (count == 2){
                // 找到队伍中另外一个队友修改队伍id为-1
                List<Integer> userIds = troopUserService.list(new QueryWrapper<TroopUser>().eq("troop_id", troopId).select("u_id")).stream().map(TroopUser::getUId).collect(Collectors.toList());
                Integer otherUserId = userIds.get(0).compareTo(Integer.valueOf(uId)) == 0 ? userIds.get(1) : userIds.get(0);
                TaskRecord setTaskRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().select("id","file_path").eq("t_id", taskId).eq("u_id", otherUserId));
                String filePath = setTaskRecord.getFilePath();
                setTaskRecord(setTaskRecord);
                taskRecordService.updateById(setTaskRecord);
                // 删除队伍
                troopService.removeById(troopId);
                // 删除troop_user
                troopUserService.remove(new QueryWrapper<TroopUser>().eq("troop_id",troopId));
                // 因为队伍解散了,则队伍中上传的文件也要删除
                if (!ObjectUtils.isEmpty(filePath)){
                    OSSUtil.deleteFile(filePath);
                }
            }else {
                troopUserService.remove(new QueryWrapper<TroopUser>().eq("troop_id",troopId).eq("u_id",uId));
            }
            TaskRecord setRecord = taskRecordService.getOne(new QueryWrapper<TaskRecord>().select("id","troop_id").eq("t_id", taskId).eq("u_Id", uId));
            setTaskRecord(setRecord);
            taskRecordService.updateById(setRecord);
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error().message(e.toString());
        }
        return R.ok();

    }

    // 退出队伍后把文件相关信息设置为空
    private void setTaskRecord(TaskRecord taskRecord){
        taskRecord.setTroopId(-1);
        taskRecord.setIsSubmit(false);
        taskRecord.setFileName("");
        taskRecord.setFilePath("");
        taskRecord.setFileSize(0l);
        taskRecord.setUrl("");
        taskRecord.setSubmitTime(null);
    }

}
